package com.zhang.novel.service.impl;

import com.zhang.novel.entity.Author;
import com.zhang.novel.mapper.AuthorCodeDynamicSqlSupport;
import com.zhang.novel.mapper.AuthorCodeMapper;
import com.zhang.novel.mapper.AuthorDynamicSqlSupport;
import com.zhang.novel.mapper.AuthorMapper;
import com.zhang.novel.service.AuthorService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

import static org.mybatis.dynamic.sql.SqlBuilder.*;
import static org.mybatis.dynamic.sql.select.SelectDSL.select;

@Service
@RequiredArgsConstructor
public class AuthorServiceImpl implements AuthorService {

    private final AuthorMapper authorMapper;

    private final AuthorCodeMapper authorCodeMapper;

    @Override
    public Boolean checkPenName(String penName) {
        SelectStatementProvider selectStatementProvider = select(count(AuthorDynamicSqlSupport.id))
                .from(AuthorDynamicSqlSupport.author)
                .where(AuthorDynamicSqlSupport.penName, isEqualTo(penName))
                .build()
                .render(RenderingStrategies.MYBATIS3);
        return authorMapper.count(selectStatementProvider) > 0;
    }

    @Override
    public Author queryAuthor(Long userId) {
        SelectStatementProvider selectStatementProvider = select(AuthorDynamicSqlSupport.author.allColumns())
                .from(AuthorDynamicSqlSupport.author)
                .where(AuthorDynamicSqlSupport.userId, isEqualTo(userId))
                .build()
                .render(RenderingStrategies.MYBATIS3);
        return authorMapper.selectMany(selectStatementProvider).get(0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String register(Long userId, Author author) {
        Date currentDate = new Date();

        // 判断邀请码是否有效
        SelectStatementProvider selectStatementProvider = select(count(AuthorCodeDynamicSqlSupport.id))
                .from(AuthorCodeDynamicSqlSupport.authorCode)
                .where(AuthorCodeDynamicSqlSupport.inviteCode, isEqualTo(author.getInviteCode()))
                .and(AuthorCodeDynamicSqlSupport.isUse, isEqualTo((byte) 0))
                .and(AuthorCodeDynamicSqlSupport.validityTime, isGreaterThan(currentDate))
                .build()
                .render(RenderingStrategies.MYBATIS3);
        long count = authorCodeMapper.count(selectStatementProvider);
        if (count > 0) {
            // 邀请码有效
            // 保存作家信息
            author.setUserId(userId);
            author.setCreateTime(currentDate);
            authorMapper.insertSelective(author);

            // 设置邀请码已被使用
            UpdateStatementProvider updateStatementProvider = update(AuthorCodeDynamicSqlSupport.authorCode)
                    .set(AuthorCodeDynamicSqlSupport.isUse)
                    .equalTo((byte) 1)
                    .where(AuthorCodeDynamicSqlSupport.inviteCode, isEqualTo(author.getInviteCode()))
                    .build()
                    .render(RenderingStrategies.MYBATIS3);
            authorCodeMapper.update(updateStatementProvider);
            return "";
        } else {
            return "邀请码无效！";
        }
    }

    @Override
    public Boolean isAuthor(Long userId) {
        SelectStatementProvider selectStatementProvider = select(count(AuthorDynamicSqlSupport.id))
                .from(AuthorDynamicSqlSupport.author)
                .where(AuthorDynamicSqlSupport.userId, isEqualTo(userId))
                .build()
                .render(RenderingStrategies.MYBATIS3);
        return authorMapper.count(selectStatementProvider) > 0;
    }
}
